package org.robot.scm.utils;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import com.alibaba.fastjson.JSONAware;
import com.alibaba.fastjson.JSONObject;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.robot.scm.infra.ProxyHelper;
import org.robot.scm.pojos.proxy.ProxyInfo;

@Slf4j
public class RequestHelper {

    /**
     * 指定代理
     */
    public static String get(String url, ProxyInfo proxyInfo) {
        HttpRequest httpRequest = HttpUtil.createGet(url);
        httpRequest.setReadTimeout(30000);
        httpRequest.setConnectionTimeout(30000);
        if (Objects.nonNull(proxyInfo)) {
            httpRequest.setHttpProxy(proxyInfo.getProxyIp(), proxyInfo.getProxyPort());
        }
        return httpRequest.execute().body();
    }

    /**
     * 封装HTTP GET方法
     */
    public static String get(String url) {
        HttpRequest httpRequest = HttpUtil.createGet(url);
        httpRequest.setReadTimeout(30000);
        httpRequest.setConnectionTimeout(30000);
        ProxyInfo proxyInfo = ProxyHelper.get();
        if (Objects.nonNull(proxyInfo) && telnet(proxyInfo, 2000)) {
            httpRequest.setHttpProxy(proxyInfo.getProxyIp(), proxyInfo.getProxyPort());
        }
        return httpRequest.execute().body();
    }

    public static String get(String url, Map<String, String> headers) {
        HttpRequest httpRequest = HttpUtil.createGet(url);
        httpRequest.addHeaders(headers);
        httpRequest.setReadTimeout(30000);
        httpRequest.setConnectionTimeout(30000);
        ProxyInfo proxyInfo = ProxyHelper.get();
        if (Objects.nonNull(proxyInfo) && telnet(proxyInfo, 2000)) {
            httpRequest.setHttpProxy(proxyInfo.getProxyIp(), proxyInfo.getProxyPort());
        }
        return httpRequest.execute().body();
    }

    @SneakyThrows
    public static String post(String url, JSONObject data) {
        HttpRequest httpRequest = HttpUtil.createRequest(Method.POST, url);
        httpRequest.setReadTimeout(30000);
        httpRequest.setConnectionTimeout(30000);
        ProxyInfo proxyInfo = ProxyHelper.get();
        if (Objects.nonNull(proxyInfo) && telnet(proxyInfo, 1500)) {
            httpRequest.setHttpProxy(proxyInfo.getProxyIp(), proxyInfo.getProxyPort());
        }
        return httpRequest.body(Optional.ofNullable(data).map(JSONAware::toJSONString).orElse(null)).execute().body();
    }

    @SneakyThrows
    public static String post(String url, String data) {
        try {
            HttpRequest httpRequest = HttpUtil.createRequest(Method.POST, url);
            httpRequest.setReadTimeout(30000);
            httpRequest.setConnectionTimeout(30000);
            ProxyInfo proxyInfo = ProxyHelper.get();
            if (Objects.nonNull(proxyInfo) && telnet(proxyInfo, 1500)) {
                httpRequest.setHttpProxy(proxyInfo.getProxyIp(), proxyInfo.getProxyPort());
            }
            return httpRequest.body(data).execute().body();
        } catch (Exception e) {
            log.warn(url, e);
        }
        return "";
    }


    @SneakyThrows
    public static String post(String url, Map<String, String> headers, JSONObject data) {
        HttpRequest httpRequest = HttpUtil.createRequest(Method.POST, url);
        httpRequest.addHeaders(headers);
        httpRequest.setReadTimeout(30000);
        httpRequest.setConnectionTimeout(30000);
        ProxyInfo proxyInfo = ProxyHelper.get();
        if (Objects.nonNull(proxyInfo) && telnet(proxyInfo, 1500)) {
            httpRequest.setHttpProxy(proxyInfo.getProxyIp(), proxyInfo.getProxyPort());
        }
        return httpRequest.body(Optional.ofNullable(data).map(JSONAware::toJSONString).orElse(null)).execute().body();
    }

    /**
     * 代理可用检测
     */
    private static boolean telnet(ProxyInfo proxyInfo, int timeout) {
        try (Socket socket = new Socket()) {
            socket.connect(new InetSocketAddress(proxyInfo.getProxyIp(), proxyInfo.getProxyPort()), timeout);
            return socket.isConnected();
        } catch (IOException e) {
            ProxyHelper.remove(proxyInfo.getProxyIp());
        }
        return false;
    }

}
